<template>
  <a-col v-if="formflag" :span="theSpan" :md="theMd" :sm="theSm" :xs="theXs" :lg="theLg" :xl="theXl" :xxl="theXxl">
    <a-form-model-item :ref="prop" :label="label" :prop="prop" :labelCol="theLabelCol" :wrapperCol="theWrapperCol">
      <a-tooltip :title="compact?help:null" :mouseLeaveDelay="1">
        <a-input v-if="type==='text'" :style="inputStyle" :allowClear="allowClear" :addonBefore="addonBefore"
                 :addonAfter="addonAfter" :prefix="prefix" :suffix="suffix" :disabled="theDisabled" v-model="modelValue"
                 :placeholder="placeholder" :maxLength="maxLength"
                 @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @change="onFieldChange"
                 @pressEnter="onPressEnter" @focus="onFocus">
          <slot/>
        </a-input>
        <a-textarea v-if="type==='textarea'" :addonBefore="addonBefore" :rows="rows" :prefix="prefix"
                    :allowClear="allowClear" :disabled="theDisabled" v-model="modelValue" :placeholder="placeholder"
                    :autoSize="autoSize" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                    @change="onFieldChange" @pressEnter="onPressEnter" @focus="onFocus">
          <slot/>
        </a-textarea>
        <a-input-number v-if="type==='number'" :addonBefore="addonBefore" :prefix="prefix" :allowClear="allowClear"
                        style="width:100%" :disabled="theDisabled" v-model="modelValue" :maxLength="maxLength"
                        :formatter="formatter" :parser="parser" :min="min" :max="max" :step="step"
                        @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @change="onFieldChange"
                        @pressEnter="onPressEnter" @focus="onFocus">
          <slot/>
        </a-input-number>
        <a-dropdown :trigger="['click']" v-if="type==='search'" v-model="searchVisible"
                    :disabled="theDisabled"
                    :getPopupContainer="
                      triggerNode => {
                        return triggerNode.parentNode || document.body;
                      }
                    "
        >
          <div slot="overlay" :style="{width:theSearchWidth}">
            <zh-table ref="searchTable" :showOverflow="false" :shadow="true" type="default" size="mini" :stripe="false"
                      :rowId="rowId" :showHeader="false" :height="searchTableHeight" @cell-click="searchCellClick"
                      @cell-dblclick="searchCellDbclick" :layouts="[  'PrevPage', 'Number', 'NextPage',   'Total']"
                      :data="searchTalbeData" :columns="tableColumn" border="inner">
              <template v-if="searchFormatField&&searchFormatField.length>0" #contentDefault="{ row }">
                            <span v-for="(item, index) in searchFormatField" :key="index">
                                <span v-if="index>0">{{ searchFormatSplit }}</span><span>{{ row[item] }}</span>
                            </span>
              </template>
            </zh-table>
          </div>
          <a-input-search ref="zhSearchInput" :addonBefore="addonBefore" :prefix="prefix" :allowClear="allowClear"
                          v-model="modelValue" :placeholder="placeholder" style="width:100%" :maxLength="maxLength"
                          :enter-button="enterButton" :loading="theLoading" @search="onInputSearch"
                          @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @change="onSearchChange"
                          @pressEnter="onPressEnter" @focus="onFocus">
            <slot/>
          </a-input-search>
        </a-dropdown>
        <a-input-password v-if="type==='password'" :addonBefore="addonBefore" :prefix="prefix" :disabled="theDisabled"
                          :allowClear="allowClear" v-model="modelValue" :placeholder="placeholder"
                          :maxLength="maxLength" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                          @change="onFieldChange" @pressEnter="onPressEnter" @focus="onFocus">
          <slot/>
        </a-input-password>
        <a-select v-if="type==='select'" :key="modelValue?modelValue.length:'idx0'" :style="inputStyle"
                  option-label-prop="label" :mode="mode" :showSearch="showSearch" v-model="modelValue"
                  :label-in-value="labelInValue" :not-found-content="notFoundContent"
                  :allowClear="allowClear" :filter-option="filterOption" :disabled="theDisabled"
                  :placeholder="placeholder" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                  @change="onSelectChange" @focus="onFocus" @search="onSearch" @select="onSelect" @deselect="onDeselect"
                  @dropdownVisibleChange="onDropdownVisibleChange">
          <a-select-option v-for="item in selectOptions" :key="item[nodeValue]" :value="item[nodeValue]"
                           :disabled="item.disabled?item.disabled:false" :label="item[nodeLabel]"
                           :title="item[nodeValue]+item[nodeLabel]">
            <span slot="label" v-if="item.icon"><a-icon type="item.icon"/><span
                style="padding-left:3px">{{ item[nodeLabel] }}</span></span>
            <span slot="label" v-if="!item.icon"><span v-if="showKey">{{ item[nodeValue] }} - </span>{{
                item[nodeLabel]
              }}</span>
          </a-select-option>
          <slot/>
        </a-select>
        <a-date-picker style="width:100%;min-width:0px" v-if="type==='date'" :allowClear="allowClear" v-model="modelValue"
                       :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                       :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                       @change="onDateChange" @ok="onOk" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                       @focus="onFocus" @openChange="onOpenChange" @panelChange="onPanelChange"
                       :disabled-date="disabledDate" :disabled-time="disabledDateTime">
          <slot/>
        </a-date-picker>
        <a-date-picker style="width:100%" v-if="type==='year'" :allowClear="allowClear" v-model="modelValue"
                       :disabled="theDisabled" format="YYYY" :showToday="showToday" :valueFormat="theFormat"
                       :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                       @change="onDateChange" @ok="onOk" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                       @focus="onFocus" @openChange="onOpenChange" @panelChange="onPanelChange"
                       :disabled-date="disabledDate" :disabled-time="disabledDateTime" mode="year" :open="yearShow">
          <slot/>
        </a-date-picker>
        <a-month-picker style="width:100%" v-if="type==='month'" :allowClear="allowClear" v-model="modelValue"
                        :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                        :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                        @change="onDateChange" @ok="onOk" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                        @focus="onFocus" @openChange="onOpenChange" @panelChange="onPanelChange">
          <slot/>
        </a-month-picker>
        <a-week-picker style="width:100%" v-if="type==='week'" :allowClear="allowClear" v-model="modelValue"
                       :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                       :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                       @change="onDateChange" @ok="onOk" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                       @focus="onFocus" @openChange="onOpenChange" @panelChange="onPanelChange">
          <slot/>
        </a-week-picker>
        <a-range-picker style="width:100%" v-if="type==='range'" :allowClear="allowClear" v-model="modelValue"
                        :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                        :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                        @change="onDateChange" @ok="onOk" @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}"
                        @focus="onFocus" @openChange="onOpenChange" @panelChange="onPanelChange"
                        :disabled-date="disabledDate" :disabled-time="disabledDateTime">
          <slot/>
        </a-range-picker>
        <a-time-picker style="width:100%" v-if="type==='time'" :allowClear="allowClear" v-model="modelValue"
                       :disabled="theDisabled" :inputReadOnly="inputReadOnly" :format="theFormat"
                       :valueFormat="theFormat" :placeholder="placeholder" :use12Hours="use12Hours"
                       :hideDisabledOptions="hideDisabledOptions" :hourStep="hourStep" :minuteStep="minuteStep"
                       :secondStep="secondStep" :disabledHours="disabledHours" :disabledMinutes="disabledMinutes"
                       :disabledSeconds="disabledSeconds" :clearText="clearText"
                       @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @focus="onFocus"
                       @change="onDateChange" @openChange="onOpenChange">
          <slot/>
        </a-time-picker>
        <a-tree-select v-if="type==='tree'" style="width: 100%" :treeNodeFilterProp="treeNodeFilterProp"
                       :dropdownStyle="dropdownStyle" :dropdownMatchSelectWidth="dropdownMatchSelectWidth"
                       :showSearch="showSearch" :multiple="multiple" :labelInValue="labelInValue" :treeIcon="treeIcon"
                       :treeDefaultExpandAll="treeDefaultExpandAll" :treeCheckable="treeCheckable"
                       :treeCheckStrictly="treeCheckStrictly" :allowClear="allowClear" :loadData="loadData"
                       :show-checked-strategy=showCheckedStrategy
                       :replaceFields="replaceFields" v-model="modelValue" :disabled="theDisabled" :tree-data="treeData"
                       :placeholder="placeholder" :searchPlaceholder="searchPlaceholder"
                       @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @change="onTreeChange"
                       @focus="onFocus" @search="onSearch" @select="onTreeSelect">
          <slot/>
        </a-tree-select>
        <a-cascader v-if="type==='cascader'" style="width: 100%" :allowClear="allowClear"
                    :changeOnSelect="changeOnSelect" v-model="modelValue" :showSearch="showSearch?{theFilter}:showSearch"
                    :disabled="theDisabled" :loadData="loadData" :options="options" :placeholder="placeholder"
                    :fieldNames="fieldNames" :expandTrigger="expandTrigger" @change="onDateChange"
                    @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @focus="onFocus" @search="onSearch"
                    @popupVisibleChange="onPopupVisibleChange">
          <slot/>
        </a-cascader>
        <a-switch v-if="type==='switch'" v-model="swichModelValue" :disabled="theDisabled" :size="size"
                  :defaultChecked="defaultChecked" :checkedChildren="checkedChildren"
                  :unCheckedChildren="unCheckedChildren" @change="onDateChange" @click="onClick"
                  @blur="() => {$refs[prop].onFieldBlur();this.onFieldBlur();}" @focus="onFocus">
          <slot/>
        </a-switch>
      </a-tooltip>
      <div v-if="type==='description'" class="myText">
        <div class="zh-text" :style="theDisabled?{'background-color': '#f5f5f5'}:''">
          {{ value }}
        </div>
      </div>
    </a-form-model-item>
  </a-col>
  <div v-else>
    <a-input v-if="type==='text'" :style="inputStyle" :allowClear="allowClear" :addonBefore="addonBefore"
             :addonAfter="addonAfter" :prefix="prefix" :suffix="suffix" :disabled="theDisabled" v-model="modelValue"
             :placeholder="placeholder" :maxLength="maxLength" @blur="onFieldBlur" @change="onFieldChange"
             @pressEnter="onPressEnter" @focus="onFocus">
      <slot/>
    </a-input>
    <a-textarea v-if="type==='textarea'" :addonBefore="addonBefore" :rows="rows" :prefix="prefix"
                :allowClear="allowClear" :disabled="theDisabled" v-model="modelValue" :placeholder="placeholder"
                :autoSize="autoSize" @blur="onFieldBlur" @change="onFieldChange" @pressEnter="onPressEnter"
                @focus="onFocus">
      <slot/>
    </a-textarea>
    <a-input-number v-if="type==='number'" :addonBefore="addonBefore" :prefix="prefix" :allowClear="allowClear"
                    style="width:100%" :disabled="theDisabled" v-model="modelValue" :maxLength="maxLength"
                    :formatter="formatter" :parser="parser" :min="min" :max="max" :step="step" @blur="onFieldBlur"
                    @change="onFieldChange" @pressEnter="onPressEnter" @focus="onFocus">
      <slot/>
    </a-input-number>
    <a-dropdown :trigger="['click']" v-if="type==='search'" v-model="searchVisible"  :disabled="theDisabled">
      <div slot="overlay" :style="{width:theSearchWidth}">
        <zh-table ref="searchTable" :showOverflow="false" :shadow="true" type="default" size="mini" :stripe="false"
                  :rowId="rowId" :showHeader="false" :height="searchTableHeight" @cell-click="searchCellClick"
                  @cell-dblclick="searchCellDbclick" :layouts="[  'PrevPage', 'Number', 'NextPage',   'Total']"
                  :data="searchTalbeData" :columns="tableColumn" border="inner">
          <template v-if="searchFormatField&&searchFormatField.length>0" #contentDefault="{ row }">
                        <span v-for="(item, index) in searchFormatField" :key="index">
                            <span v-if="index>0">{{ searchFormatSplit }}</span><span>{{ row[item] }}</span>
                        </span>
          </template>
        </zh-table>
      </div>
      <a-input-search ref="zhSearchInput" :addonBefore="addonBefore" :prefix="prefix" :allowClear="allowClear"
                      v-model="modelValue" :placeholder="placeholder" style="width:100%" :maxLength="maxLength"
                      :enter-button="enterButton" :loading="theLoading" @search="onInputSearch" @blur="onFieldBlur"
                      @change="onSearchChange" @pressEnter="onPressEnter" @focus="onFocus">
        <slot/>
      </a-input-search>
    </a-dropdown>
    <a-input-password v-if="type==='password'" :addonBefore="addonBefore" :prefix="prefix" :disabled="theDisabled"
                      :allowClear="allowClear" v-model="modelValue" :placeholder="placeholder" :maxLength="maxLength"
                      @blur="onFieldBlur" @change="onFieldChange" @pressEnter="onPressEnter" @focus="onFocus">
      <slot/>
    </a-input-password>

    <a-select v-if="type==='select'" :key="modelValue?modelValue.length:'idx0'" :style="inputStyle"
              option-label-prop="label" :mode="mode" :showSearch="showSearch" v-model="modelValue"
              :allowClear="allowClear" :filter-option="filterOption" :disabled="theDisabled" :placeholder="placeholder"
              @blur="onFieldBlur" @change="onSelectChange" @focus="onFocus" @search="onSearch" @select="onSelect"
              @deselect="onDeselect" @dropdownVisibleChange="onDropdownVisibleChange">
      <a-select-option v-for="item in selectOptions" :key="item[nodeValue]" :value="item[nodeValue]"
                       :disabled="item.disabled?item.disabled:false" :label="item[nodeLabel]"
                       :title="item[nodeValue]+item[nodeLabel]">
        <span slot="label" v-if="item.icon"><a-icon type="item.icon"/><span
            style="padding-left:3px">{{ item[nodeLabel] }}</span></span>
        <span slot="label" v-if="!item.icon"><span v-if="showKey">{{ item[nodeValue] }} - </span>{{
            item[nodeLabel]
          }}</span>
      </a-select-option>
      <slot/>
    </a-select>
    <a-date-picker style="width:100%" v-if="type==='date'" :allowClear="allowClear" v-model="modelValue"
                   :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                   :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder" @change="onDateChange"
                   @ok="onOk" @blur="onFieldBlur" @focus="onFocus" @openChange="onOpenChange"
                   @panelChange="onPanelChange" :disabled-date="disabledDate" :disabled-time="disabledDateTime">
      <slot/>
    </a-date-picker>
    <a-month-picker style="width:100%" v-if="type==='month'" :allowClear="allowClear" v-model="modelValue"
                    :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                    :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                    @change="onDateChange" @ok="onOk" @blur="onFieldBlur" @focus="onFocus" @openChange="onOpenChange"
                    @panelChange="onPanelChange">
      <slot/>
    </a-month-picker>
    <a-week-picker style="width:100%" v-if="type==='week'" :allowClear="allowClear" v-model="modelValue"
                   :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                   :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder" @change="onDateChange"
                   @ok="onOk" @blur="onFieldBlur" @focus="onFocus" @openChange="onOpenChange"
                   @panelChange="onPanelChange">
      <slot/>
    </a-week-picker>
    <a-range-picker style="width:100%" v-if="type==='range'" :allowClear="allowClear" v-model="modelValue"
                    :disabled="theDisabled" :format="theFormat" :showToday="showToday" :valueFormat="theFormat"
                    :showTime="showTime" :inputReadOnly="inputReadOnly" :placeholder="placeholder"
                    @change="onDateChange" @ok="onOk" @blur="onFieldBlur" @focus="onFocus" @openChange="onOpenChange"
                    @panelChange="onPanelChange" :disabled-date="disabledDate" :disabled-time="disabledDateTime">
      <slot/>
    </a-range-picker>
    <a-time-picker style="width:100%" v-if="type==='time'" :allowClear="allowClear" v-model="modelValue"
                   :disabled="theDisabled" :inputReadOnly="inputReadOnly" :format="theFormat" :valueFormat="theFormat"
                   :placeholder="placeholder" :use12Hours="use12Hours" :hideDisabledOptions="hideDisabledOptions"
                   :hourStep="hourStep" :minuteStep="minuteStep" :secondStep="secondStep" :disabledHours="disabledHours"
                   :disabledMinutes="disabledMinutes" :disabledSeconds="disabledSeconds" :clearText="clearText"
                   @blur="onFieldBlur" @focus="onFocus" @change="onDateChange" @openChange="onOpenChange">
      <slot/>
    </a-time-picker>
    <a-tree-select v-if="type==='tree'" style="width: 100%" :treeNodeFilterProp="treeNodeFilterProp"
                   :dropdownStyle="dropdownStyle" :dropdownMatchSelectWidth="dropdownMatchSelectWidth"
                   :showSearch="showSearch" :multiple="multiple" :labelInValue="labelInValue" :treeIcon="treeIcon"
                   :treeDefaultExpandAll="treeDefaultExpandAll" :treeCheckable="treeCheckable"
                   :treeCheckStrictly="treeCheckStrictly" :allowClear="allowClear" :loadData="loadData"
                   :show-checked-strategy=showCheckedStrategy
                   :replaceFields="replaceFields" v-model="modelValue" :disabled="theDisabled" :tree-data="treeData"
                   :placeholder="placeholder" :searchPlaceholder="searchPlaceholder" @blur="onFieldBlur"
                   @change="onTreeChange" @focus="onFocus" @search="onSearch" @select="onTreeSelect">
      <slot/>
    </a-tree-select>
    <a-cascader v-if="type==='cascader'" style="width: 100%" :allowClear="allowClear" :changeOnSelect="changeOnSelect"
                v-model="modelValue" :showSearch="showSearch?{theFilter}:showSearch" :disabled="theDisabled"
                :loadData="loadData" :options="options" :placeholder="placeholder" :fieldNames="fieldNames"
                :expandTrigger="expandTrigger" @change="onDateChange" @blur="onFieldBlur" @focus="onFocus"
                @search="onSearch" @popupVisibleChange="onPopupVisibleChange">
      <slot/>
    </a-cascader>

    <a-switch key="swichModelValue" v-if="type==='switch'" v-model="swichModelValue" :disabled="theDisabled"
              :size="size"
              :defaultChecked="defaultChecked" :checked-children="checkedChildren"
              :unCheckedChildren="unCheckedChildren" @change="onDateChange" @click="onClick" @blur="onFieldBlur"
              @focus="onFocus">
      <slot/>
    </a-switch>
    <div v-if="type==='description'" class="myText">
      <div class="zh-text" :style="theDisabled?{'background-color': '#f5f5f5'}:''">
        {{ value }}
      </div>
    </div>
  </div>
</template>
<script>
import moment from 'moment'
import {getDictSearchData} from "@/services/system/api"
export default {
  name: 'ZhInput',
  props: {
    //输入框类型 text 普通文本框 number 数字文本框  password 密码输入框 search 搜索框 textarea 文本域 select 下拉框 date 日期
    type: {
      type: String,
      default: "text"
    },
    // 是否在form中使用
    formflag: {
      type: Boolean,
      default: true
    },
    prop: {
      type: String,
      default: ""
    },
    //内容样式控制
    inputStyle: {
      type: String,
      default: ""
    },
    //是否可编辑
    disabled: {
      type: Boolean,
      default: null
    },
    //设置输入框为只读（避免在移动设备上打开虚拟键盘）
    inputReadOnly: {
      type: Boolean,
      default: false
    },
    //可以点击清除图标删除内容
    allowClear: {
      type: Boolean,
      default: true
    },
    //显示下拉值的key
    showKey: {
      type: Boolean,
      default: false
    },
    // 搜索按钮
    enterButton: {
      type: [Boolean, String],
      default: true
    },
    loading: {
      type: Boolean,
      default: false
    },
    //下拉菜单的样式
    dropdownStyle: {
      type: Object,
      default() {
        return undefined
      }
    },
    //下拉菜单和选择器同宽
    dropdownMatchSelectWidth: {
      type: Boolean,
      default: true
    },
    //带标签的 input，设置后置标签
    addonAfter: {
      type: String,
      default: ""
    },
    //带标签的 input，设置前置标签
    addonBefore: {
      type: String,
      default: ""
    },
    //带有前缀图标的 input
    prefix: {
      type: String,
      default: ""
    },
    //带有后缀图标的 input
    suffix: {
      type: String,
      default: ""
    },
    //最大长度
    maxLength: {
      type: Number,
      default: -1
    },
    rows: {
      type: Number,
      default: 1
    },
    //自适应内容高度，可设置为 true|false 或对象：{ minRows: 2, maxRows: 6 }
    autoSize: {
      type: [Object, Boolean],
      default() {
        return false
      }
    },
    //number 最大值
    min: {
      type: Number,
      default: -Infinity
    },
    //number 最小值
    max: {
      type: Number,
      default: Infinity
    },
    //每次改变步数，可以为小数
    step: {
      type: Number,
      default: 1
    },
    //指定输入框展示值的格式
    //value => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    formatter: {
      type: Function
    },
    //指定从 formatter 里转换回数字的方式，和 formatter 搭配使用
    //value => value.replace(/\$\s?|(,*)/g, '')
    parser: {
      type: Function
    },
    //异步加载数据
    loadData: {
      type: Function
    },
    //数值精度
    precision: {
      type: Number,
      default: null
    },
    //小数点
    decimalSeparator: {
      type: String,
      default: null
    },
    label: {
      type: String,
      default: ""
    },
    placeholder: {
      type: [String, Array],
      default: undefined
    },
    searchPlaceholder: {
      type: String,
      default: undefined
    },
    //设置日期格式，为数组时支持多格式匹配，展示以第一个为准。配置参考 moment.js
    format: {
      type: [String, Array],
      default: undefined
    },
    value: [Number, String, Boolean, Array],
    //label 标签布局，同 <Col> 组件，设置 span offset 值，如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} 或者 固定宽度 :labelCol="{ style: 'width: 100px' }"
    labelCol: {
      type: Object,
      default: function () {
        return null
      }
    },
    //需要为输入控件设置布局样式时，使用该属性，用法同 labelCol 或者固定宽度搭配 :wrapperCol="{ style: {width: 'calc(100% - 100px)',display: 'inline-block'} }"
    wrapperCol: {
      type: Object,
      default: function () {
        return null
      }
    },
    options: {//select数据源
      type: [Array, Object],
      default() {
        return []
      }
    },
    treeData: {//下拉树
      type: [Array, Object],
      default() {
        return []
      }
    },
    defaultFields: {//select字段转换配置
      type: Object,
      default() {
        return {
          label: "dictValue",
          value: "dictKey",
          children: "children"
        }
      }
    },
    //设置 Select 的模式为多选或标签	'default' | 'multiple' | 'tags' | 'combobox'
    mode: {
      type: String,
      default: "default"
    },
    showSearch: {
      type: Boolean,
      default: true
    },
    //是否展示“今天”按钮
    showToday: {
      type: Boolean,
      default: true
    },
    showTime: {
      type: [Boolean, Object],
      default: false
    },
    disabledDate: {
      type: Function,
      default: () => {
        return false
      }
    },
    disabledDateTime: {
      type: Function,
      default: () => {
        return false
      }
    },
    treeNodeFilterProp: {
      type: String,
      default: "value"
    },
    treeNodeLabelProp: {
      type: String,
      default: "title"
    },
    replaceFields: {
      type: Object,
      default() {
        return {children: 'children', title: 'title', key: 'key', value: 'value'}
      }
    },
    //cascader 自定义 options 中 label name children 的字段
    fieldNames: {
      type: Object,
      default() {
        return {label: 'label', value: 'value', children: 'children'}
      }
    },
    //默认展开所有树节点
    treeDefaultExpandAll: {
      type: Boolean,
      default: false
    },
    //显示 checkbox
    treeCheckable: {
      type: Boolean,
      default: false
    },
    //heckable 状态下节点选择完全受控（父子节点选中状态不再关联），会使得 labelInValue 强制为 true
    treeCheckStrictly: {
      type: Boolean,
      default: false
    },
    //定义选中项回填的方式。TreeSelect.SHOW_ALL: 显示所有选中节点(包括父节点). TreeSelect.SHOW_PARENT: 只显示父节点(当父节点下所有子节点都选中时). 默认只显示子节点
    showCheckedStrategy:{
      type: String,
      default:"SHOW_CHILD"
    },
    //是否把每个选项的 label 包装到 value 中，会把 value 类型从 string 变为 {value: string, label: VNode, halfChecked(treeCheckStrictly 时有效): string[] } 的格式
    labelInValue: {
      type: Boolean,
      default: false
    },
    //下拉树支持多选（当设置 treeCheckable 时自动变为 true）
    multiple: {
      type: Boolean,
      default: false
    },
    //是否展示 TreeNode title 前的图标，没有默认样式，如设置为 true，需要自行定义图标相关样式
    treeIcon: {
      type: Boolean,
      default: false
    },
    //小时选项间隔
    hourStep: {
      type: Number,
      default: 1
    },
    //分钟选项间隔
    minuteStep: {
      type: Number,
      default: 1
    },
    //秒选项间隔
    secondStep: {
      type: Number,
      default: 1
    },
    //使用 12 小时制，为 true 时 format 默认为 h:mm:ss a
    use12Hours: {
      type: Boolean,
      default: false
    },
    //隐藏禁止选择的选项
    hideDisabledOptions: {
      type: Boolean,
      default: false
    },
    clearText: {
      type: String,
      default: "清除"
    },
    //禁止选择部分小时选项
    disabledHours: {
      type: Function,
      default: () => {
        return false
      }
    },

    //禁止选择部分分钟选项
    disabledMinutes: {
      type: Function,
      default: () => {
        return false
      }
    },
    //禁止选择部分秒选项
    disabledSeconds: {
      type: Function,
      default: () => {
        return false
      }
    },
    //次级菜单的展开方式，可选 'click' 和 'hover'
    expandTrigger: {
      type: String,
      default: "click"
    },
    //当此项为 true 时，点选每级菜单选项值都会发生变化，具体见上面的演示
    changeOnSelect: {
      type: Boolean,
      default: false
    },
    filter: {
      type: Function,
      default: (inputValue, path) => {
        return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
      }
    },
    //开关大小，可选值：default small
    size: {
      type: String,
      default: "default"
    },
    //初始是否选中
    defaultChecked: {
      type: Boolean,
      default: false
    },
    checkedChildren: {
      type: String,
      default: "开"
    },
    unCheckedChildren: {
      type: String,
      default: "关"
    },
    span: Number,
    //≥768px
    md: {
      type: Number,
      default: undefined
    },
    //≥576px
    sm: {
      type: Number,
      default: undefined
    },
    //<576px
    xs: {
      type: Number,
      default: undefined
    },
    //≥992px
    lg: {
      type: Number,
      default: undefined
    },
    //≥1200px
    xl: {
      type: Number,
      default: undefined
    },
    //≥1600px
    xxl: {
      type: Number,
      default: undefined
    },
    //请求数据的url
    searchUrl: {
      type: String,
      default: ""
    },
    //请求数据的参数
    searchParams: {
      type: Object,
      default: null
    },
    //搜索框显示的内容
    showSearchField: {
      type: [String, Array],
      default: null
    },
    //查询的字段内容
    searchColumn: {
      type: Array,
      default() {
        return null
      }
    },
    //查询数据
    searchData: {
      type: Array,
      default() {
        return null
      }
    },
    //查询数据主键
    searchRowId: {
      type: String,
      default: null
    },
    //查询提交到后台字段
    searchField: {
      type: String,
      default: null
    },
    //查询表格默认内容宽度
    searchTableWidth: {
      type: [String, Number],
      default: '100%'
    },
    //格式化的字段
    searchFormatField: {
      type: Array,
      default() {
        return null
      }
    },
    //搜索下拉高度
    searchTableHeight: {
      type: [String, Number],
      default: '350px'
    },
    //格式化分割符号
    searchFormatSplit: {
      type: String,
      default: '-'
    },
    // 下拉框和搜索框数据类型 default 默认 common 通用查询
    dataType: {
      type: String,
      default: 'default'
    },
    //查询参数配置
    queryParams: {
      type: Object,
      default() {
        return {
          tableName: "sys_dict",
          resultList: [],
          queryList: []
        }
      }
    },
    //搜索方法触发改变事件类型：click 单击 dbclick 双击
    searchChangeType: {
      type: String,
      default: 'click'
    },
    notFoundContent: {
      type: null | undefined,
      default: null
    }
  },
  data() {
    return {
      //form:this.getModel(),
      theLabelCol: this.labelCol ? this.labelCol : this.$parent.$options.parent.labelCol,
      theWrapperCol: this.wrapperCol ? this.wrapperCol : this.$parent.$options.parent.wrapperCol,
      modelValue: undefined,
      swichModelValue: undefined,
      help: null,
      compact: false,
      theDisabled: false,
      theSpan: this.getSpan(),
      theMd: this.getMd(),
      theSm: this.getSm(),
      theXs: this.getXs(),
      theLg: this.getLg(),
      theXl: this.getXl(),
      theXxl: this.getXxl(),
      mySpan: null,
      searchVisible: false,
      searchTalbeData: [],
      selectOptions: [],
      theLoading: false,
      inputStyWidth:'300px',
      yearShow: false
    }
  },
  created() {
    if (this.type === 'switch') {
      this.swichModelValue = !!(this.value && (this.value === 1 || this.value === '1'));
    }
    if (this.type === 'select') {
      if (this.dataType === "default") {
        this.selectOptions = this.options
      } else {
        this.getSelectList()
      }

    }
    this.modelValue = this.value

    if (this.disabled === null || this.disabled === undefined) {
      this.getDisabled()
    } else {
      this.theDisabled = this.disabled
    }
    if (this.dataType === "default") {
      this.searchTalbeData = this.searchData
    }
    this.theLoading = this.loading
  },
  watch: {
    value(val) {
      if (this.type === 'switch') {
        this.swichModelValue = !!(this.value && (this.value === 1 || this.value === '1'));
      }
      this.modelValue = val
    },
    searchData(val) {
      if (this.dataType === "default") {
        this.searchTalbeData = val
      }
    },
    disabled(val) {
      if (val === null || val === undefined) {
        this.getDisabled()
      } else {
        this.theDisabled = val
      }
    },
    options(val) {
      if (this.type === 'select' && this.dataType === "default") {
        this.selectOptions = val
      }
    },
    loading(val) {
      this.theLoading = val
    }
  },
  computed: {
    nodeLabel() {
      return this.defaultFields.label;
    },
    searchInputField() {
      if (this.showSearchField) {
        return this.showSearchField;
      } else {
        return this.defaultFields.label;
      }
    },
    nodeValue() {
      return this.defaultFields.value;
    },
    theSearchWidth(){
        let me = this;
        this.$nextTick(function () {
          me.inputStyWidth = me.$refs.zhSearchInput.$el.clientWidth + 'px';
        })
        let searchTableWidth= this.searchTableWidth
        if(searchTableWidth){
            if(searchTableWidth==='100%'){
                searchTableWidth=this.inputStyWidth
            }else{
                if(!isNaN(Number(searchTableWidth))) {
                    searchTableWidth += 'px'
                }
            }
        }else{
            searchTableWidth=this.inputStyWidth
        }
        return searchTableWidth
    },
    tableColumn() {
      if (this.searchColumn && this.searchColumn.length > 0) {
        return this.searchColumn
      } else {
        let searchColumn = []
        let value = {}
        value.field = this.defaultFields.value
        value.title = "KEY"
        value.visible = false
        value.align = 'left'
        value.width = 150
        searchColumn.push(value)
        let label = {}
        label.field = this.defaultFields.label
        label.title = "内容"
        label.align = 'left'
        label.width = this.searchTableWidth
        label.showOverflow = false
        let slots = {}
        slots.default = 'contentDefault'
        if (this.searchFormatField && this.searchFormatField.length > 0) {
          label.slots = slots
        }
        searchColumn.push(label)
        return searchColumn
      }
    },
    rowId() {
      if (this.searchRowId) {
        return this.searchRowId
      } else {
        return this.defaultFields.value
      }
    },
    theFormat() {
      if (this.format) {
        return this.format
      } else {
        let type = this.type
        let format = "YYYY-MM-DD"
        if (type === 'date') {
          if (this.showTime) {
            format = "YYYY-MM-DD HH:mm:ss"
          }
        } else if (type === 'month') {
          format = "YYYYMM"
        } else if (type === 'week') {
          format = "YYYY-第w周"
        } else if (type === 'time') {
          format = "HH:mm:ss"
        }
        return format;
      }
    },
    theFilter(){
      const defaultFunction = (inputValue, path) => {
        return path.some(option => option[this.fieldNames.label].toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
      }
      return defaultFunction
    }
  },
  methods: {
    moment,
    //失去焦点的时回调
    onFieldBlur() {
      this.$emit('blur');
    },
    //获得焦点时回调
    onFocus() {
      if (this.prop&&this.formflag) {
        let validateMessage = this.$refs[this.prop].validateMessage
        let validateState = this.$refs[this.prop].validateState
        if (validateState === 'error') {
          this.help = validateMessage
        } else {
          this.help = null
        }
      }

      this.getCompact();
      if (this.type === 'search') {
        this.querySearchList()

      }
      if (this.type === 'select' && this.dataType === 'common') {
        this.getSelectList()
      }
      this.$emit('focus');
    },
    getDisabled(data) {
      let disabled = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        disabled = parent.disabled
        if (disabled === null || disabled === undefined) {
          this.getDisabled(parent)
        } else {
          this.theDisabled = disabled
        }

      } else {
        this.theDisabled = false
      }
    },
    getCompact(data) {
      let compact = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        compact = parent.compact
        if (compact === null || compact === undefined) {
          this.getCompact(parent)
        } else {
          this.compact = compact
        }

      } else {
        this.compact = false
      }
    },
    getSpan(data) {
      if (this.span) {
        this.mySpan = this.span
        return this.span
      }
      let span = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        span = parent.span

        if (span === null || span === undefined) {
          let name = parent.$options.name
          if (name === 'ZhForm') {
            this.mySpan = undefined
            return undefined
          }
          return this.getSpan(parent)
        } else {
          this.mySpan = span
          return span
        }

      } else {
        this.mySpan = undefined
        return undefined
      }
    },
    getMd(data) {
      if (this.mySpan) {
        return undefined
      } else {
        this.getSpan()
      }
      if (this.md) {
        return this.md
      }
      let md = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        md = parent.md
        if (md === null || md === undefined) {
          return this.getMd(parent)
        } else {
          return md
        }

      } else {
        return undefined
      }
    },
    getSm(data) {
      if (this.mySpan) {
        return undefined
      } else {
        this.getSpan()
      }
      if (this.sm) {
        return this.sm
      }
      let sm = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        sm = parent.sm
        if (sm === null || sm === undefined) {
          return this.getSm(parent)
        } else {
          return sm
        }

      } else {
        return undefined
      }
    },
    getXs(data) {
      if (this.mySpan) {
        return undefined
      } else {
        this.getSpan()
      }
      if (this.xs) {
        return this.xs
      }
      let xs = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        xs = parent.xs
        if (xs === null || xs === undefined) {
          return this.getXs(parent)
        } else {
          return xs
        }

      } else {
        return undefined
      }
    },
    getLg(data) {
      if (this.mySpan) {
        return undefined
      } else {
        this.getSpan()
      }
      if (this.lg) {
        return this.lg
      }
      let lg = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        lg = parent.lg
        if (lg === null || lg === undefined) {
          return this.getLg(parent)
        } else {
          return lg
        }

      } else {
        return undefined
      }
    },
    getXl(data) {
      if (this.mySpan) {
        return undefined
      } else {
        this.getSpan()
      }
      if (this.xl) {
        return this.xl
      }
      let xl = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        xl = parent.xl
        if (xl === null || xl === undefined) {
          return this.getXl(parent)
        } else {
          return xl
        }

      } else {
        return undefined
      }
    },
    getXxl(data) {
      if (this.mySpan) {
        return undefined
      } else {
        this.getSpan()
      }
      if (this.xxl) {
        return this.xxl
      }
      let xxl = null;
      let parent = null;
      if (data) {
        parent = data.$parent;
      } else {
        parent = this.$parent;
      }
      if (parent) {
        xxl = parent.xxl
        if (xxl === null || xxl === undefined) {
          return this.getXxl(parent)
        } else {
          return xxl
        }

      } else {
        return undefined
      }
    },
    //值变化时回调
    onFieldChange(e) {
      this.$emit('input', this.modelValue);
      this.$emit('change', e);
    },
    onSelectChange(value, options) {
      this.$emit('input', this.modelValue);
      let selectOptions = this.selectOptions
      this.$emit('change', value, selectOptions);
    },
    onSearchChange(e) {
      let value = this.modelValue
      this.querySearchList()
      this.$emit('change', value);
      this.$emit('input', value);
    },
    onDateChange(date, dateString) {
      if (this.type === 'switch') {
        let checked = this.modelValue + ''
        if (checked === 'true' || checked === 'false') {
          this.modelValue = this.swichModelValue
        } else {
          if (this.swichModelValue) {
            this.modelValue = '1'
          } else {
            this.modelValue = '0'
          }

        }
      }
      this.$emit('input', this.modelValue);
      this.$emit('change', date, dateString);
    },
    //按下回车的回调
    onPressEnter(e) {
      this.$emit('pressEnter', e);
    },
    //点击搜索或按下回车键时的回调
    onSearch(value) {
      if (this.type === 'select' && this.dataType === 'common') {

        this.getSelectList(value)
      }
      this.$emit('search', value);
    },
    //点击搜索或按下回车键时的回调
    onInputSearch(value) {
      this.querySearchList()
      this.$emit('search', value);
    },
    //搜索组件列表单机击事件
    searchCellClick({row}) {
      if (this.searchChangeType === "click") {
        if (row[this.searchInputField]) {
          this.modelValue = row[this.searchInputField]
          this.$emit('input', this.modelValue)
        }
        this.searchVisible = false
      }
      this.$emit('cell-click', row)
    },
    searchCellDbclick({row}) {
      if (this.searchChangeType === "dbclick") {
        if (row[this.searchInputField]) {
          this.modelValue = row[this.searchInputField]
          this.$emit('input', this.modelValue)
        }
        this.searchVisible = false
      }
      this.$emit('cell-dblclick', row)
    },
    querySearchList() {
      if (this.dataType === 'default') {
        if (this.searchUrl) {
          let params = {}
          if(this.searchParams){
            params = this.searchParams;
          }
          params.pageNum = 1;
          params.pageSize = 100;
          let searchField = this.searchField
          if (!searchField) {
            searchField = this.nodeLabel
          }
          params[searchField] = this.modelValue
          this.theLoading = true;
          this.$http.post(this.searchUrl, params, 30000)
              .then(res => {
                this.searchTalbeData = res.result.list;
                this.theLoading = false;
              })
              .catch(() => {
                this.theLoading = false;
              });
        }
      } else {
        this.getSelectList(this.modelValue)
      }
    },
    //显示/隐藏浮层的回调
    onPopupVisibleChange(value) {
      this.$emit('popupVisibleChange', value);
    },
    //被选中时调用，参数为选中项的 value (或 key) 值
    onSelect(value, option) {
      if (this.type === 'select') {
        let selectOptions = this.selectOptions
        this.$emit('select', value, selectOptions);
      } else {
        this.$emit('select', value, option);
      }
    },
    //取消选中时调用，参数为选中项的 value (或 key) 值，仅在 multiple 或 tags 模式下生效
    onDeselect(value, option) {
      this.$emit('deselect', value, option);
    },
    //展开下拉菜单的回调
    onDropdownVisibleChange(open) {
      this.$emit('dropdownVisibleChange', open);
    },
    filterOption(input, option) {
      return (
          option.componentOptions.propsData.title.toLowerCase().indexOf(input.toLowerCase()) >= 0
      )
    },
    onOk(value) {
      this.$emit('ok', value);
    },
    onOpenChange(status) {
      if(this.type === 'year'){
        if (status){
          this.yearShow =  true
        }
      }
      this.$emit('openChange', status);
    },
    onPanelChange(value, mode) {
      if(this.type === 'year'){
        this.modelValue = value.format('YYYY');
        this.$emit('input', this.modelValue);
        this.yearShow = false;
      }
      this.$emit('panelChange', value, mode);
    },
    onTreeSelect(value, node, extra) {
      this.$emit('select', value, node, extra);
    },
    onTreeChange(value, label, extra) {
      this.$emit('input', this.modelValue);
      this.$emit('change', value, label, extra);
    },
    onClick(value, event) {
      this.$emit('click', value, event);
    },
    getModel(data) {
      let model = null;
      let parent = data;
      if (!data) {
        parent = this.$parent
      } else {
        parent = parent.$parent
      }
      model = parent.model
      if (model) {
        Object.keys(model).forEach(key => {
          if (model[key] === null || model[key] === '') {
            model[key] = undefined
          }
        })
        return model
      } else {
        return this.getModel(parent)
      }
    },
    getSelectList(value) {
      let params = Object.assign({}, this.queryParams);
      if (!params.tableName) {
        params.tableName = 'sys_dict'
      }
      let searchField = this.searchField
      if (!searchField) {
        searchField = this.nodeLabel
      }
      params.keyName = this.nodeValue
      params.valueName = this.nodeLabel
      params.searchField = searchField
      if (value) {
        params.searchText = value
      }
      if (this.type === "select") {
        if (this.modelValue && this.modelValue.length > 0) {
          if (Array.isArray(this.modelValue)) {
            params.selectList = this.modelValue
          } else {
            let selectList = []
            selectList.push(this.modelValue)
            params.selectList = selectList
          }
        }
      }
      this.theLoading = true;
      this.$http.post(getDictSearchData, params).then(res => {
        const data = res.result.list;
        if (this.type === "select") {
          this.selectOptions = data
        } else if (this.type === "search") {
          this.searchTalbeData = data;
        }
        this.theLoading = false;
      }).catch(() => {
        this.theLoading = false;
      })
    }

  }
}
</script>
<style lang="less">
// .ant-input[disabled] {
//   color: rgba(0, 0, 0, 0.65);
//   background-color: #f5f5f5;
//   cursor: not-allowed;
//   opacity: 1;
// }

// .ant-input-number-disabled {
//   color: rgba(0, 0, 0, 0.65);
//   background-color: #f5f5f5;
//   cursor: not-allowed;
//   opacity: 1;
// }

// .ant-input-number[disabled] {
//   color: rgba(0, 0, 0, 0.65);
//   background-color: #f5f5f5;
//   cursor: not-allowed;
//   opacity: 1;
// }

// .ant-select-disabled {
//   color: rgba(0, 0, 0, 0.65);
// }

// .ant-cascader-picker-disabled {
//   color: rgba(0, 0, 0, 0.65);
//   background: #f5f5f5;
//   cursor: not-allowed;
// }

// .ant-time-picker-input-disabled {
//   color: rgba(0, 0, 0, 0.65);
//   background-color: #f5f5f5;
//   cursor: not-allowed;
//   opacity: 1;
// }

// .ant-time-picker-input[disabled] {
//   color: rgba(0, 0, 0, 0.65);
//   background-color: #f5f5f5;
//   cursor: not-allowed;
//   opacity: 1;
// }

// .ant-input-disabled {
//   color: rgba(0, 0, 0, 0.65);
// }

// .myText {
//   box-sizing: border-box;
//   margin: 0;
//   position: relative;
//   display: inline-block;
//   width: 100%;
//   min-height: 32px;
//   height: auto;
//   padding: 4px 11px;
//   color: rgba(0, 0, 0, 0.65);
//   border-style: none none solid none;
//   border-color: #d9d9d9;
//   border-radius: 0;
//   background-color: #fff;
//   font-size: 14px;
//   line-height: 1.5;
//   border-width: 1px;

//   .zh-text {
//     line-height: 20px;
//   }
// }
</style>
